{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nuclide Naming Conventions\n",
    "==========================\n",
    "One of the most basic aspects of nuclear software is how to uniquely represent \n",
    "nuclide names.  There exists a large number of different ways that people choose \n",
    "to spell these names.  Functionally, there are three pieces of information that *should* \n",
    "be included in every radionuclide's name:\n",
    "\n",
    "1. **Z Number**: The number of protons.\n",
    "2. **A Number**: The number of nucleons (neutrons + protons).\n",
    "3. **S Number**: The internal energy excitation state of the nucleus.\n",
    "\n",
    "Some common naming conventions exist. The following are currently supported by PyNE:\n",
    "\n",
    " * **id (ZAS)**: This type places the charge of the nucleus out front, then has three\n",
    "   digits for the atomic mass number, and ends with four state digits (0 = ground,\n",
    "   1 = first metastable state, 2 = second metastable state, etc).  Uranium-235 has\n",
    "   92 protons and an atomic mass number of 235. It would be expressed as '922350000'\n",
    "   This is the canonical form for nuclides.\n",
    " * **name**: This is the more common, human readable notation.  The chemical symbol\n",
    "   (one or two characters long) is first, followed by the atomic weight.  Lastly if\n",
    "   the nuclide is metastable, the letter *M* is concatenated to the end.  For\n",
    "   example, 'H-1' and 'Am242M' are both valid.  Note that nucname will always\n",
    "   return name form with the dash removed and all letters uppercase.\n",
    " * **zzaaam**: This type places the charge of the nucleus out front, then has three\n",
    "   digits for the atomic mass number, and ends with a metastable flag (0 = ground,\n",
    "   1 = first excited state, 2 = second excited state, etc).  Uranium-235 here would\n",
    "   be expressed as '922350'.\n",
    " * **SZA**: This type places three state digits out front, the charge of the nucleus in \n",
    "   the middle, and then has three digits for the atomic mass number. Uranium-235M here \n",
    "   would be expressed as '1092235'.  \n",
    " * **MCNP**: The MCNP format for entering nuclides is unfortunately\n",
    "   non-standard.  In most ways it is similar to zzaaam form, except that it\n",
    "   lacks the metastable flag.  For information on how metastable isotopes are\n",
    "   named, please consult the MCNPX documentation for more information.\n",
    " * **Serpent**: The serpent naming convention is similar to name form.\n",
    "   However, only the first letter in the chemical symbol is uppercase, the\n",
    "   dash is always present, and the the meta-stable flag is lowercase.  For\n",
    "   instance, 'Am-242m' is the valid serpent notation for this nuclide.\n",
    " * **NIST**: The NIST naming convention is also similar to the Serpent form.\n",
    "   However, this convention contains no metastable information.  Moreover, the\n",
    "   A-number comes before the element symbol.  For example, '242Am' is the\n",
    "   valid NIST notation.\n",
    " * **CINDER**: The CINDER format is similar to zzaaam form except that the\n",
    "   placement of the Z- and A-numbers are swapped. Therefore, this format is\n",
    "   effectively aaazzzm.  For example, '2420951' is the valid cinder notation\n",
    "   for 'AM242M'.\n",
    " * **ALARA**: In ALARA format, elements are denoted by the lower case atomic symbol. Isotopes are\n",
    "   specified by appending a semicolon and A-number. For example, \"fe\" and \"fe:56\" represent\n",
    "   elemental iron and iron-56 respectively. No metastable flag exists.\n",
    " * **state_id**: State id format is similar to **id** except that it refers to each energy level in\n",
    "   the order they are reported in the ENSDF file. This can change between ENSDF releases as more \n",
    "   levels are added so it is not the default id form."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------------\n",
    "\n",
    "Canonical Form\n",
    "--------------\n",
    "A [canonical form](http://en.wikipedia.org/wiki/Canonical_form) is \n",
    "*\"a representation such that every object has a unique representation.\"*\n",
    "Since there are many ways to represent nuclides, PyNE chooses one of them\n",
    "to be *the* canonical form.  **Note:** this idea of \n",
    "canonical forms will come up many times in PyNE.\n",
    "\n",
    "The **id** integer form of nuclide names is the fundamental form of nuclide naming because\n",
    "it accurately captures all of the needed information in the smallest amount of space.  Given that the \n",
    "Z-number may be up to three digits, A-numbers are always three digits, and the excitation level is\n",
    "4 digits, all possible nuclides are represented on the range ``10000000 < zzaaam < 2130000000``. \n",
    "This falls well within 32 bit integers.\n",
    "\n",
    "The ``id()`` function converts other representations to the id format. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyne import nucname"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "922350000"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.id('U-235')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "952420001"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.id('Am-242m')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While applications and backends should use the **id** form under-the-covers, the **name** form provides an easy way to covert nuclide to a consistent and human readable representation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'U235'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.name(922350000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'H1'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.name(10010000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Cm244M'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.name('CM-244m')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The **name** string representations may be anywhere from two characters (16 bits)\n",
    "up to six characters (48 bits).  So in general, **id** is smaller by 50%.  \n",
    "\n",
    "Other forms do not necessarily contain all of the required information (``MCNP``) or require additional \n",
    "storage space (``Serpent``).  It may seem pedantic to quibble over the number of bits per nuclide name, \n",
    "but these identifiers are used everywhere throughout nuclear code, so it behooves us to be as small\n",
    "and fast as possible."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The other distinct advantage that integer forms have is that you can natively perform arithmetic\n",
    "on them.  For example::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Z-number: 95\n",
      "A-number: 242\n",
      "State: 1\n"
     ]
    }
   ],
   "source": [
    "# Am-242m\n",
    "nuc = 952420001\n",
    "\n",
    "# Z-number\n",
    "z = nuc//10000000\n",
    "print(f'Z-number:',z)\n",
    "\n",
    "# A-number\n",
    "a = (nuc//10000)%1000\n",
    "print(f'A-number:',a)\n",
    "\n",
    "# state\n",
    "s = nuc%10000\n",
    "print(f'State:',s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, there are built in functions to do exactly this as well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Z-number: 95\n",
      "A-number: 242\n",
      "State: 1\n"
     ]
    }
   ],
   "source": [
    "print(f'Z-number:',nucname.znum(nuc))\n",
    "print(f'A-number:',nucname.anum(nuc))\n",
    "print(f'State:',nucname.snum(nuc))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code internal to PyNE uses **id**, and except for human readability, you should too! Natural elements are specified in this form by having zero A-number and excitation flags."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "920000000"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.id('U')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---------\n",
    "\n",
    "# Ambiguous Forms\n",
    "\n",
    "For some nuclides and forms, ambiguities may arise. For example \"10000\" is elemental neon in MCNP and elemental hydrogen in ZZAAAM. To resolve such ambiquities when you *know* which form you are coming from, PyNE provides a suite of `*_to_id()` functions. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100000000"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# MCNP\n",
    "nucname.mcnp_to_id(10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10000000"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# ZZAAAM\n",
    "nucname.zzaaam_to_id(10000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-------------------\n",
    "\n",
    "Examples of Use\n",
    "---------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "922350"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.zzaaam('U235')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'H1'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.name(10010)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Am-242m'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.serpent('AM242M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "38"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.name_zz['Sr']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'La'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.zz_name[57]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'fe:56'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.alara('FE56')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "952420002"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nucname.id_to_state_id(952420001)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
